package com.gdkj.util;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.HexUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.RSA;

import javax.crypto.Cipher;
import java.nio.charset.StandardCharsets;
import java.security.KeyFactory;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

/**
 * 采用hutool工具实现rsa加密解密
 */
public class RSAUtils {
/*    public static void main(String[] args) throws Exception {
        //公钥私钥使用蚂蚁金服秘钥工具生成
        String publicKeyBase64 = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA21BHFmJTYgQNgJmhynkRgyMEWbGH6JP2YAkIVr80fAavHZgKWzfPXHF1MPFiMIZy7vpIOORvVJ99oOkvh6Cr6a6+0oRUqQtZBTcAvXfMsWxICOyUMjZoadS2+x6Z19af+lE11Y+zGs9w5pxKA796lww0aQqotKH3cVEDw5R7mzqmwWYmbvQORPRvbsb+cfrwiTh6nibr0r3OqjtAx8e/IsnWDXIKGcToPbHXcnTS+bORwZ21vzEMFWQguvITQday8xTsXe2x9u6bMmEIE3QT8x4Q//achMyBKEf2qaJIKxPiL6fCTC+V96rzBGd55TYOmGWJhH3ABqCMJGh4Yb20aQIDAQAB";
        String privateKeyBase64 = "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbUEcWYlNiBA2AmaHKeRGDIwRZsYfok/ZgCQhWvzR8Bq8dmApbN89ccXUw8WIwhnLu+kg45G9Un32g6S+HoKvprr7ShFSpC1kFNwC9d8yxbEgI7JQyNmhp1Lb7HpnX1p/6UTXVj7Maz3DmnEoDv3qXDDRpCqi0ofdxUQPDlHubOqbBZiZu9A5E9G9uxv5x+vCJOHqeJuvSvc6qO0DHx78iydYNcgoZxOg9sddydNL5s5HBnbW/MQwVZCC68hNB1rLzFOxd7bH27psyYQgTdBPzHhD/9pyEzIEoR/apokgrE+Ivp8JML5X3qvMEZ3nlNg6YZYmEfcAGoIwkaHhhvbRpAgMBAAECggEAGYovvRuWOkPejqtVfA69S1g4mXljKmKQvn5OyktaAVeF7RxXmGfXbhyIWTrDBIOjvtDGuFlh3aj1KFf/gPvlCUGgV0Ox2D3KECFnpKje3YqOmPt0BqTvY+Oxq2zU3Z3Q44Wxjz08zlJ6A2EP/X++9vgk4larbt2twzR8C7qu6lSjAXIlUuHlTdO/itcaVc7nMBkNBPP97B9Zk48P6Mmz+3+TZNP0z53wGYdhddO993QcWL7KDLvFCQX4zdRnPH4FeT9M96AYnYeey9Liej5GfjUP61tzWrGVjGteihMq4FfzPlOgTr5zIZCVidTrRFs9hG8FL1ON9TYSw6y5llYQQQKBgQDzhw3loKV9HA16eCRVzTCguA/ntw0Mtv4qGygdf6yp6yfgl0c9OlyR5TWv02qfK/iJWwepM2gYYl7mQQTz6sIVPUSHazA+Ez+1FLaJIUUq4a57Fg4nDHFsjhE3QxLEMSNGSuN6wU8EidLtEZxu5fZjhxGqxvd9CDnevzhgV3AHvwKBgQDmi7+bVmImXkRtw/a+wGNeV1KIPGaFekwQVeVnLXxU6J7Gnz7fAA2lhmOincq+94XF9Pi0rfASITV4EV2oKlvt+DQCgIYqcVxfSrD+PMHwKbxlD6GoyTrfACdaUhv2LEswWHX4CID5i8YTBCcupN3toL1GYGJlDDhBMa7YEl2N1wKBgEYNP24ie/g1LZthG/Kih65zw/9/pH1X1lz+WtfBdkWao2nzmkZ+l0pQiNT/F9iZqXC5gsalRvhcs7fAVFBl41aAvUnHB6WTm+vW/XsM2vyu1qYJfiC1b5sucr1Wyfstt1vtBuq02KoRi18uhbVQ6UNQA0EA4whQaXUtxGXSQSO5AoGAS225mNcgcbEx7j/JQQus9zbWt+AbItyqekXAMou9PAKHwDBl34wi6t8XRiMeLHDLgcLuhB7MhwH6fnggDl8diLRGP/NQ8h34vOyxD91NDoh5LQ96MsDz0/Y26eQnZdmEGCM5JZeSqxLCEYKwVyB1w8NtadMrHihrV1kr/WG03i0CgYAWKc5vTOWd2uoBdI+aTiZ3QivQBfV0Yi+Xl0muhCN0HoJk/FW1ICn1fX0LN6WWKnC2BSOXbcUasAQtwSYLm2lTCP/G7tNYh3q4CoNoqqKVg8N9F7s/89CHT8yK7UZaGweQwcJF6vkhJtNX5VEJx33rL43y3UN64mGcxqzqsAtlfw==";
        System.out.println("公钥:" + publicKeyBase64);
        System.out.println("私钥:" + privateKeyBase64);
        String str = "黄河远上白云间，一片孤城万仞山。羌笛何须怨杨柳，春风不度玉门关。";
        System.out.println("原始报文:" + str);
        String encode = encode(publicKeyBase64, str);
        System.out.println("公钥加密后:" + encode);
        String decode = decode(privateKeyBase64, encode);
        System.out.println("私钥解密后:" + decode);
    }*/


    /**
     * 公钥加密
     *
     * @param publicKey
     * @param val
     * @return
     */
    public static String encode(String publicKey, String val) {
        //hutool的Rsa工具
        RSA rsa = new RSA(null, publicKey);
        //字符串转字节数组
        byte[] bytes = StrUtil.bytes(val, CharsetUtil.CHARSET_UTF_8);
        //加密
        byte[] encrypt = rsa.encrypt(bytes, KeyType.PublicKey);
        //字节转16进制
        String str = HexUtil.encodeHexStr(encrypt);
        //16进制转base64
        String encode = Base64.encode(str);
        return encode;
    }

    /**
     * 私钥解密
     *
     * @param privateKey
     * @param val
     * @return
     */
    public static String decode(String privateKey, String val) {
        RSA rsa = new RSA(privateKey, null);
        //base转解码,解码后是16进制
        String base64Str = Base64.decodeStr(val);
        //16进制转字节数组
        byte[] bytes = HexUtil.decodeHex(base64Str);
        //私钥解密
        byte[] decrypt = rsa.decrypt(bytes, KeyType.PrivateKey);
        //字节数组转字符串
        String str = StrUtil.str(decrypt, CharsetUtil.CHARSET_UTF_8);
        return str;
    }

    /**
     * RSA公钥加密
     * @param str 加密字符串
     * @param publicKey 公钥
     * @return 密文
     * @throws Exception 加密过程中的异常信息
     *
     */
    public static String rasEncrypt( String str, String publicKey ) throws Exception{
        //base64编码的公钥
        byte[] decoded = java.util.Base64.getDecoder().decode(publicKey);
        RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(decoded));
        //RSA加密
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, pubKey);
        return java.util.Base64.getEncoder().encodeToString(cipher.doFinal(str.getBytes(StandardCharsets.UTF_8)));
    }

    /**
     * RSA私钥解密
     * @param str  加密字符串
     * @param privateKey 私钥
     * @return 明文
     * @throws Exception 解密过程中的异常信息
     */
    public static String rasDecrypt(String str, String privateKey) throws Exception{
        //64位解码加密后的字符串
        byte[] inputByte = java.util.Base64.getDecoder().decode(str);
        //base64编码的私钥
        byte[] decoded = java.util.Base64.getDecoder().decode(privateKey);
        PKCS8EncodedKeySpec a = new PKCS8EncodedKeySpec(decoded);
        RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(a);
        //RSA解密
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE, priKey);
        return new String(cipher.doFinal(inputByte));
    }
}
